/**
 * Reads metadata from linked classes i.e. if documentClass is set to
 * com.ydp.ExampleDocumentClass script tries to read ./com/ydp/ExampleDocumentClass.as
 *
 * Suported metadata:
 * [Nexl.Activator]
 * [Nexl.Attr(attr=value)]
 *
 * Also all library items linked as assets.%symbolName% are added to library xml as
 *
 * Example output:
 * <library src="navBar.swf">
 *	<ext implementation="com.ydp.pdf2flash.view.NavBar">
 *		<attr name="type" value="com.ydp.pdf2flash.view.INavBar" />
 *		<attr name="width" value="1024" />
 *		<attr name="height" value="26" />
 *	</ext>
 *	<activator class="com.ydp.pdf2flash.view.NavBarActivator" />
 *	<ext implementation="com.ydp.pdf2flash.view.NavBarActivator">
 *		<attr name="type" value="IActivator" />
 *	</ext>
 *	<ext implementation="assets.rightArrow">
 *		</attr name="baseClass" value="flash.display.MovieClip">
 *	</ext>
 *	<ext implementation="assets.btRightArrow">
 *		</attr name="baseClass" value="flash.display.SimpleButton">
 *	</ext>
 * </library>
 *
 * Example usage with Nexl lib:
 * 	var libLoader:GatheringLibraryLoader = new GatheringLibraryLoader();
 *	Nexl.library = libLoader;
 *	libLoader.addEventListener( Event.COMPLETE, librariesLoaded);
 *	libLoader.addEventListener( IOErrorEvent.IO_ERROR, librariesLoadError);
 *	libLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, librariesLoadError);
 *	libLoader.add("skin.xml");
 *	libLoader.load();
 * 
 *	var exts:Array = Nexl.library.list( { type: "com.ydp.pdf2flash.view.ITopBar" } );
 *	var ext:INexlExtensionDescription = exts[0] as INexlExtensionDescription;
 *	var topBar:ITopBar = ext.create() as ITopBar;
 *	addChild(topBar as DisplayObject);
 *
 */
function generateLibXML() {
	fl.outputPanel.clear();
	var doc = fl.getDocumentDOM();
	if ( fl.documents.length==0 ) {
		alert( "No documents opened" )
	} else if (doc.path==undefined) {
		alert("Document must be saved");
	} else {
		var basepath = getBasePath();
		var startXml = "<library src=\""+document.name.split(".fla")[0]+".swf\">\r\n";
		var xml = "";
		// read annotations from document class
		if (doc.docClass) {
			xml += getMetadata(basepath, doc.docClass);
		}
		// read annotations from linked symbols
		for (var i=0;i<doc.library.items.length;i++) {
			var item = doc.library.items[i];
			if (item.linkageExportForAS) {
				xml += getMetadata( basepath, item.linkageClassName, {baseClass: getBaseClass(item.itemType) });
			}
		}
		endXml = "</library>"
		if (xml=="") {
			alert("No annotations found in linked classes");
		} else {
			xml = startXml + xml + endXml;
			fl.clipCopyString(xml);
			fl.trace(xml);
			fl.trace("library.xml was copied to clipboard");
		}
	}
}

function getBasePath() {
	var basepath = fl.getDocumentDOM().path
	var fileIndex = basepath.lastIndexOf("\\");
	basepath = basepath.split(":").join("|");
	basepath = basepath.split("\\").join("/");
	basepath = "file:///" + basepath.substring(0,fileIndex) + "/";
	return basepath;
}

function getBaseClass(itemType) {
	var baseClass;
	switch (itemType){
		case "button":
			baseClass = "flash.display.SimpleButton";
			break;
		case "movie clip":
			baseClass = "flash.display.MovieClip";
			break;
		case "bitmap":
			baseClass = "flash.display.BitmapData";
			break;
		case "sound":
			baseClass = "flash.media.Sound";
			break;
		default:
			baseClass = null;
			break;
	}
	return baseClass;
}	

function getMetadata(basepath, className, params ) {
	var filepath = basepath + className.split(".").join("/")+".as";
	var xml = "";
	// [Nexl.Activator]
	var activatorRE = new RegExp("\\[Nexl\\.Activator\\]");
	// [Nexl.Attr(Implements="pl.ydp.ExampleImplementation")]
	// [Nexl.Attr(width=1024)]
	var attrRE = new RegExp( "\\[Nexl\\.Attr\\((.*)=\"?([^\"\)]*)\"?\\)\\]", "g");
	var assetRE = /^assets\.(.*)$/;
	var str = FLfile.read(filepath);
	if (str) {
		var activator = str.match(activatorRE);
		if (activator) {
			xml = "\t<activator class=\""+className+"\" />\r\n"
		}
		var impl;
		var found = false;
		while ((impl = attrRE.exec(str)) != null)
		{
			if (!found) {
				xml += "\t<ext implementation=\"" +className + "\">\r\n";
				found = true;
			}
			var name = new String(impl[1]);
			var value = new String(impl[2]);
			xml += "\t\t<attr name=\""+trim(impl[1])+"\" value=\""+trim(impl[2])+"\" />\r\n"
		}
		if (found) {
			xml += "\t</ext>\r\n";
		}
	} else {
		var asset = assetRE.exec(className);
		if ( asset ) {
			if (params && params["baseClass"]) {
				xml += "\t<ext implementation=\"" +className + "\">\r\n";
				xml += "\t\t<attr name=\"baseClass\" value=\"" + params["baseClass"] + "\" />\r\n";
				xml += "\t\t<attr name=\"id\" value=\"" + trim(asset[1]) + "\" />\r\n";
				xml += "\t</ext>\r\n";		
			}
		}
	}
	return xml;
}

function trim(str) { 
	return str.replace(/^\s+|\s+$/g, ""); 
}

try {
	generateLibXML();
} catch (error) {
	fl.trace(error);
}